/************************************************************
** @brief   : app_simple_page
** @author  : vandoul
** @github  : https://gitee.com/vandoul
** @date    : 2022-01
** @version : v1.0.0
** @note    : app_simple_page.c
***********************************************************/

#include <rtdevice.h>
#include <time.h>
#include "simple_page.h"
#include "epd_paint.h"


/* defined the LED1 pin: PA8 */
#define LED1_PIN    67

#undef SMPLPAGE_EVENT_OK
#undef SMPLPAGE_EVENT_NEXT
#undef SMPLPAGE_EVENT_PREV
#undef SMPLPAGE_EVENT_BACK
#undef SMPLPAGE_EVENT_DRAW
#define SMPLPAGE_EVENT_PREV         (1<<0)
#define SMPLPAGE_EVENT_OK           (1<<1)
#define SMPLPAGE_EVENT_NEXT         (1<<2)
#define SMPLPAGE_EVENT_BACK         (1<<3)
#define SMPLPAGE_EVENT_DRAW         (1<<4)
#define SMPLPAGE_EVENT_ALARM        (1<<5)
#define SMPLPAGE_EVENT_ALL          (SMPLPAGE_EVENT_OK|SMPLPAGE_EVENT_NEXT|SMPLPAGE_EVENT_PREV|SMPLPAGE_EVENT_BACK|SMPLPAGE_EVENT_DRAW|SMPLPAGE_EVENT_ALARM)

#define UTC_TIME_2000_01_01_00_00_00        (946659600)
#define UTC_TIME_2099_12_31_23_59_59        (4102415999)

struct _user_param {
    int32_t set_time;
    int8_t time_config_pos_max;
    int8_t time_config_pos;
};

extern const char *str_wday[];
extern const int epd_colored;
extern epd_paint_t epd_paint;
extern rt_event_t user_epd_evt;

rt_event_t simple_page_evt;

static simple_page_page_event_t simple_page_event_wait(void)
{
    simple_page_page_event_t ret = SIMPLE_PAGE_PAGE_EVENT_UNKNOWN;
    uint32_t evt;
    if(rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_ALL, RT_EVENT_FLAG_OR, 20, &evt) == RT_EOK) {
        if(evt&SMPLPAGE_EVENT_OK) {
            rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_OK, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0, RT_NULL);
            ret = SIMPLE_PAGE_PAGE_EVENT_OK;
        } else if(evt&SMPLPAGE_EVENT_NEXT) {
            rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_NEXT, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0, RT_NULL);
            ret = SIMPLE_PAGE_PAGE_EVENT_NEXT;
        } else if(evt&SMPLPAGE_EVENT_PREV) {
            rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_PREV, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0, RT_NULL);
            ret = SIMPLE_PAGE_PAGE_EVENT_PREV;
        } else if(evt&SMPLPAGE_EVENT_BACK) {
            rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_BACK, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0, RT_NULL);
            ret = SIMPLE_PAGE_PAGE_EVENT_BACK;
        } else if(evt&SMPLPAGE_EVENT_DRAW) {
            rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_DRAW, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0, RT_NULL);
            ret = SIMPLE_PAGE_PAGE_EVENT_DRAW;
        } else if(evt&SMPLPAGE_EVENT_ALARM) {
            rt_event_recv(simple_page_evt, SMPLPAGE_EVENT_ALARM, RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0, RT_NULL);
            ret = (simple_page_page_event_t)(_SIMPLE_PAGE_PAGE_EVENT_END + SIMPLE_PAGE_EVENT_ALARM);
        }
    }
    return ret;
}
static void simple_clock_page_draw(simple_page_t page, simple_page_page_t page_page, simple_page_page_event_t evt, void *param)
{
    epd_paint_t paint = epd_paint;
    char str[32];//2022-02-07 11:53:00
//    rt_kprintf("from simple_clock_page_draw:%s\r\n", simple_page_page_get_name(page_page));
    if(rt_strcmp(simple_page_page_get_name(page_page), "clock") == 0) {
        static time_t last_tim = 0;
        time_t t = time(NULL);
        t = t / 60 * 60;
        if((last_tim != t) || (evt == SIMPLE_PAGE_PAGE_EVENT_IN)) {
            last_tim = t;
            struct tm *ltm = localtime(&t);
            epd_paint_clear(paint, !epd_colored);
            rt_sprintf(str, "%d-%02d-%02d %s", ltm->tm_year+1900, ltm->tm_mon+1, ltm->tm_mday, str_wday[ltm->tm_wday]);
            epd_paint_draw_string_at(paint, 125, 32, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
            rt_sprintf(str, "%02d:%02d", ltm->tm_hour, ltm->tm_min);
            epd_paint_draw_string_at(paint, 125, 64, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
            rt_event_send(user_epd_evt, 1);
        }
    } else if(evt == SIMPLE_PAGE_PAGE_EVENT_IN) {
        epd_paint_clear(paint, !epd_colored);
        rt_sprintf(str, "exit");
        epd_paint_draw_string_at(paint, 125, (128 - 24) / 2, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
        rt_event_send(user_epd_evt, 1);
    }
}
static void simple_stopwatch_page_draw(simple_page_t page, simple_page_page_t page_page, simple_page_page_event_t evt, void *param)
{
    char str[32];//2022-02-07 11:53:00
    epd_paint_t paint = epd_paint;
//    rt_kprintf("from simple_stopwatch_page_draw:%s\r\n", simple_page_page_get_name(page_page));
    if(rt_strcmp(simple_page_page_get_name(page_page), "subpage") == 0) {
        struct _user_param *user_param = (struct _user_param*)param;
        if((evt == SIMPLE_PAGE_PAGE_EVENT_IN) && user_param) {
            rt_memset(user_param, 0, sizeof(struct _user_param));
            user_param->time_config_pos_max = 6;//00:00:00
        }
        if(user_param) {
            static time_t start_tim = 0;
            time_t t;
            bool is_start = user_param->time_config_pos >= user_param->time_config_pos_max;
            if(!is_start) {
                start_tim = time(NULL);
            }
            t = start_tim + user_param->set_time;
            struct tm *ltm = localtime(&t);
            epd_paint_clear(paint, !epd_colored);
            rt_sprintf(str, "%02d:%02d:%02d", ltm->tm_hour, ltm->tm_min, ltm->tm_sec); //target time.
            rt_kprintf("time:%s\r\n", str);
            epd_paint_draw_string_at(paint, 125, 32, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
            if(is_start && start_tim) {
                t = user_param->set_time + start_tim - time(NULL);
                if(t > 86400) { //24h
                    start_tim = 0;
                    t = 0;
                    user_param->time_config_pos = 0;
                    user_param->set_time = 0;
                    is_start = false;
                    rt_event_send(simple_page_evt, SMPLPAGE_EVENT_ALARM);
                }
            } else {
                t = user_param->set_time;
            }
            ltm = gmtime(&t);
            rt_sprintf(str, "%02d:%02d:%02d", ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
            rt_kprintf("stop:%s\r\n", str);
            if(is_start) {
                epd_paint_draw_string_at(paint, 125, 64, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
            } else {
                int pos = user_param->time_config_pos;
                if(pos > 3) {
                    pos += 2;
                } else if(pos > 1) {
                    pos += 1;
                }
                epd_paint_draw_string_at_with_invert(paint, 125, 64, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored, pos, pos+1);
            }
            rt_event_send(user_epd_evt, 1);
        } else if(evt == SIMPLE_PAGE_PAGE_EVENT_IN) {
            epd_paint_clear(paint, !epd_colored);
            rt_sprintf(str, "invalid param!");
            epd_paint_draw_string_at(paint, 125, (128-24)/2, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
            rt_event_send(user_epd_evt, 1);
        }
    } else if(evt == SIMPLE_PAGE_PAGE_EVENT_IN) {
        epd_paint_clear(paint, !epd_colored);
        rt_sprintf(str, "stopwatch");
        epd_paint_draw_string_at(paint, 125, (128-24)/2, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
        rt_event_send(user_epd_evt, 1);
    }
}
static void simple_setting_page_draw(simple_page_t page, simple_page_page_t page_page, simple_page_page_event_t evt, void *param)
{
    char str[32];//2022-02-07 11:53:00
    epd_paint_t paint = epd_paint;
//    rt_kprintf("from simple_setting_page_draw:%s\r\n", simple_page_page_get_name(page_page));
    if(rt_strcmp(simple_page_page_get_name(page_page), "subpage") == 0) {
        struct _user_param *user_param = (struct _user_param*)param;
        if((evt == SIMPLE_PAGE_PAGE_EVENT_IN) && user_param) {
            rt_memset(user_param, 0, sizeof(struct _user_param));
            user_param->time_config_pos_max = 12;//yy-MM-dd hh:mm:ss
        }
        if(user_param) {
            bool is_set = user_param->time_config_pos >= user_param->time_config_pos_max;
            time_t t = time(NULL) + user_param->set_time;
            struct tm ltm = *localtime(&t);
            rt_kprintf("set_time:%d, %d,%d\r\n", user_param->set_time, t);
            if(is_set) {
                set_time(ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
                set_date(ltm.tm_year+1900, ltm.tm_mon+1, ltm.tm_mday);
                simple_page_set_current_page(page, simple_page_page_get_parent(page_page)); //return
            } else {
                epd_paint_clear(paint, !epd_colored);
                rt_sprintf(str, "%04d-%02d-%02d", ltm.tm_year+1900, ltm.tm_mon+1, ltm.tm_mday);
                rt_kprintf("date:%s\r\n", str);
                int pos = user_param->time_config_pos;
                if(pos < 6) {
                    if(pos > 3) {
                        pos += 4;
                    } else if(pos > 1) {
                        pos += 3;
                    } else {
                        pos += 2;
                    }
                    epd_paint_draw_string_at_with_invert(paint, 125, 32, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored, pos, pos+1);
                } else {
                    epd_paint_draw_string_at(paint, 125, 32, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
                }
                rt_sprintf(str, "%02d:%02d:%02d", ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
                rt_kprintf("time:%s\r\n", str);
                pos = user_param->time_config_pos;
                if(pos >= 6) {
                    pos -= 6;
                    if(pos > 3) {
                        pos += 2;
                    } else if(pos > 1) {
                        pos += 1;
                    }
                    epd_paint_draw_string_at_with_invert(paint, 125, 64, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored, pos, pos+1);
                } else {
                    epd_paint_draw_string_at(paint, 125, 64, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
                }
                rt_event_send(user_epd_evt, 1);
            }
        } else if(evt == SIMPLE_PAGE_PAGE_EVENT_IN) {
            epd_paint_clear(paint, !epd_colored);
            rt_sprintf(str, "invalid param!");
            epd_paint_draw_string_at(paint, 125, (128-24)/2, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
            rt_event_send(user_epd_evt, 1);
        }
    } else if(evt == SIMPLE_PAGE_PAGE_EVENT_IN){
        epd_paint_clear(paint, !epd_colored);
        rt_sprintf(str, "setting");
        epd_paint_draw_string_at(paint, 125, (128-24)/2, str, &font24, EPD_PAINT_ALIGN_CENTER, epd_colored);
        rt_event_send(user_epd_evt, 1);
    }
}
void simple_page_alarm_stop_alarm(void *param)
{
    rt_pin_write(LED1_PIN, PIN_LOW);
    rt_pin_mode(LED1_PIN, PIN_MODE_INPUT);
}
static void simple_page_alarm(simple_page_t page, simple_page_event_t evt, void *param)
{
    static rt_timer_t stop_timer = RT_NULL;
    if(stop_timer == RT_NULL) {
        stop_timer= rt_timer_create("stop", simple_page_alarm_stop_alarm, &stop_timer, rt_tick_from_millisecond(1000), RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
    }
    if(stop_timer != RT_NULL) {
        rt_timer_start(stop_timer);
        rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
        rt_pin_write(LED1_PIN, PIN_HIGH);
    }
}
RT_UNUSED static void simple_page_event_do_nothing(simple_page_t page, simple_page_page_t page_page, simple_page_page_event_t evt, void *param)
{
}
RT_UNUSED static void simple_page_event_ok_callback(simple_page_t page, simple_page_page_t page_page, simple_page_page_event_t evt, void *param)
{
    rt_kprintf("from simple_page_event_ok_callback:%s,%d\r\n", simple_page_page_get_name(page_page), evt);
    if(rt_strcmp(simple_page_page_get_name(page_page), "subpage") == 0) {
        if(rt_strcmp(simple_page_page_get_name(simple_page_page_get_parent(page_page)), "stopwatch") == 0) {
            struct _user_param *user_param = (struct _user_param*)param;
            if(user_param) {
                if(user_param->time_config_pos < user_param->time_config_pos_max) {
                    user_param->time_config_pos ++;
                }
            } else {
                rt_kprintf("from simple_page_event_ok_callback:%s,%d, invalid user_param!\r\n", simple_page_page_get_name(page_page), evt);
            }
        } else if(rt_strcmp(simple_page_page_get_name(simple_page_page_get_parent(page_page)), "setting") == 0) {
            struct _user_param *user_param = (struct _user_param*)param;
            if(user_param) {
                if(user_param->time_config_pos < user_param->time_config_pos_max) {
                    user_param->time_config_pos ++;
                }
            } else {
                rt_kprintf("from simple_page_event_ok_callback:%s,%d, invalid user_param!\r\n", simple_page_page_get_name(page_page), evt);
            }
        } else {
            rt_kprintf("from simple_page_event_ok_callback unknown page!!!\r\n", simple_page_page_get_name(simple_page_page_get_parent(page_page)), evt);
        }
    } else {
        simple_page_set_current_page(page, simple_page_page_get_child(page_page));
    }
}
RT_UNUSED static void simple_page_event_prev_or_next_callback(simple_page_t page, simple_page_page_t page_page, simple_page_page_event_t evt, void *param)
{
    extern time_t timegm(struct tm * const t);
    struct _user_param *user_param = (struct _user_param*)param;
    if(user_param) {
        simple_page_page_t parent_page = simple_page_page_get_parent(page_page);
        if(rt_strcmp(simple_page_page_get_name(parent_page), "stopwatch") == 0) {
            time_t t = user_param->set_time;
            struct tm *ltm = gmtime(&t);
            if(evt == SIMPLE_PAGE_PAGE_EVENT_PREV) {
                if(user_param->time_config_pos == 0) { //10hour
                    if(ltm->tm_hour >= 10) {
                        ltm->tm_hour -= 10;
                    }
                } else if(user_param->time_config_pos == 1) {//hour
                    if(ltm->tm_hour > 0) {
                        ltm->tm_hour -= 1;
                    }
                } else if(user_param->time_config_pos == 2) { //10min
                    if(ltm->tm_min >= 10) {
                        ltm->tm_min -= 10;
                    }
                } else if(user_param->time_config_pos == 3) { //min
                    if(ltm->tm_min > 0) {
                        ltm->tm_min -= 1;
                    }
                } else if(user_param->time_config_pos == 4) { //10sec
                    if(ltm->tm_sec >= 10) {
                        ltm->tm_sec -= 10;
                    }
                } else if(user_param->time_config_pos == 5) { //sec
                    if(ltm->tm_sec > 0) {
                        ltm->tm_sec -= 1;
                    }
                }
                user_param->set_time = timegm(ltm);
            } else if(evt == SIMPLE_PAGE_PAGE_EVENT_NEXT) {
                if(user_param->time_config_pos == 0) { //10hour
                    if(ltm->tm_hour < 14) {
                        ltm->tm_hour += 10;
                    }
                } else if(user_param->time_config_pos == 1) {//hour
                    if(ltm->tm_hour < 23) {
                        ltm->tm_hour += 1;
                    }
                } else if(user_param->time_config_pos == 2) { //10min
                    if(ltm->tm_min < 49) {
                        ltm->tm_min += 10;
                    }
                } else if(user_param->time_config_pos == 3) { //min
                    if(ltm->tm_min < 59) {
                        ltm->tm_min += 1;
                    }
                } else if(user_param->time_config_pos == 4) { //10sec
                    if(ltm->tm_sec < 49) {
                        ltm->tm_sec += 10;
                    }
                } else if(user_param->time_config_pos == 5) { //sec
                    if(ltm->tm_sec < 59) {
                        ltm->tm_sec += 1;
                    }
                }
                user_param->set_time = timegm(ltm);
            } else {
                rt_kprintf("from simple_page_event_prev_or_next_callback:%s,%d, unknown event!\r\n", simple_page_page_get_name(page_page), evt);
            }
        } else if(rt_strcmp(simple_page_page_get_name(parent_page), "setting") == 0) {
            time_t cur_tim = time(NULL);
            time_t t = cur_tim + user_param->set_time;
            struct tm *ltm = localtime(&t);
            //time_t since 1970, tm since 1900
            if(evt == SIMPLE_PAGE_PAGE_EVENT_PREV) {
                if(user_param->time_config_pos == 0) { //10year
                    if(ltm->tm_year >= 110) { //great than 2000=>100
                        ltm->tm_year -= 10;
                    }
                } else if(user_param->time_config_pos == 1) {//year
                    if(ltm->tm_year > 100) {
                        ltm->tm_year -= 1;
                    }
                } else if(user_param->time_config_pos == 2) { //10mon
                    ltm->tm_mon -= 10;
                } else if(user_param->time_config_pos == 3) { //mon
                    ltm->tm_mon -= 1;
                } else if(user_param->time_config_pos == 4) { //10day
                    ltm->tm_mday -= 10;
                } else if(user_param->time_config_pos == 5) { //day
                    ltm->tm_mday -= 1;
                } else if(user_param->time_config_pos == 6) { //10hour
                    ltm->tm_hour -= 10;
                } else if(user_param->time_config_pos == 7) {//hour
                    ltm->tm_hour -= 1;
                } else if(user_param->time_config_pos == 8) { //10min
                    ltm->tm_min -= 10;
                } else if(user_param->time_config_pos == 9) { //min
                    ltm->tm_min -= 1;
                } else if(user_param->time_config_pos == 10) { //10sec
                    ltm->tm_sec -= 10;
                } else if(user_param->time_config_pos == 11) { //sec
                    ltm->tm_sec -= 1;
                }
                t = mktime(ltm);
                if(t < UTC_TIME_2000_01_01_00_00_00) { //2000-1-1 00:00:00
                    t = UTC_TIME_2000_01_01_00_00_00;
                }
                user_param->set_time = t - cur_tim;
            } else if(evt == SIMPLE_PAGE_PAGE_EVENT_NEXT) {
                if(user_param->time_config_pos == 0) { //10year
                    if(ltm->tm_year < 189) { //less than 2099=>199
                        ltm->tm_year += 10;
                    }
                } else if(user_param->time_config_pos == 1) {//year
                    if(ltm->tm_year < 199) {
                        ltm->tm_year += 1;
                    }
                } else if(user_param->time_config_pos == 2) { //10mon
                    ltm->tm_mon += 10;
                } else if(user_param->time_config_pos == 3) { //mon
                    ltm->tm_mon += 1;
                } else if(user_param->time_config_pos == 4) { //10day
                    ltm->tm_mday += 10;
                } else if(user_param->time_config_pos == 5) { //day
                    ltm->tm_mday += 1;
                } else if(user_param->time_config_pos == 6) { //10hour
                    ltm->tm_hour += 10;
                } else if(user_param->time_config_pos == 7) {//hour
                    ltm->tm_hour += 1;
                } else if(user_param->time_config_pos == 8) { //10min
                    ltm->tm_min += 10;
                } else if(user_param->time_config_pos == 9) { //min
                    ltm->tm_min += 1;
                } else if(user_param->time_config_pos == 10) { //10sec
                    ltm->tm_sec += 10;
                } else if(user_param->time_config_pos == 11) { //sec
                    ltm->tm_sec += 1;
                }
                t = mktime(ltm);
                if(t > UTC_TIME_2099_12_31_23_59_59) { //2099-12-31 23:59:59
                    t = UTC_TIME_2099_12_31_23_59_59;
                }
                user_param->set_time = t - cur_tim;
            } else {
                rt_kprintf("from simple_page_event_prev_or_next_callback:%s,%d, unknown event!\r\n", simple_page_page_get_name(page_page), evt);
            }
        }
    } else {
        rt_kprintf("from simple_page_event_prev_or_next_callback:%s,%d, invalid user_param!\r\n", simple_page_page_get_name(page_page), evt);
    }
}
static void simple_page_timer_cb(void *param)
{
    rt_event_t evt = (rt_event_t)param;
    rt_event_send(evt, SMPLPAGE_EVENT_DRAW);
}

typedef void (*simple_page_page_add_callback_t)(simple_page_page_t page, simple_page_page_t page_page);
static simple_page_page_t simple_page_page_new(
    simple_page_page_t parent_page_page, 
    const char *name, 
    simple_page_page_event_callback_t func_draw, 
    void *param, 
    simple_page_page_add_callback_t func) 
{
    simple_page_page_t page_page;
    page_page = simple_page_page_create(name, func_draw, param);
    if(page_page != RT_NULL) {
        func(parent_page_page, page_page);
    }
    return page_page;
}
/*
clock
  | - exit
  | - stopwatch - subpage
   \- setting - subpage
*/
static void simple_page_task(void *param)
{
    simple_page_evt = rt_event_create("smplPage", RT_IPC_FLAG_FIFO);
    if(simple_page_evt == RT_NULL) {
        rt_kprintf("create smplPage failed!\r\n");
        return ;
    }
    rt_timer_t simple_timer = rt_timer_create("simple", simple_page_timer_cb,simple_page_evt, rt_tick_from_millisecond(1000), RT_TIMER_FLAG_SOFT_TIMER|RT_TIMER_FLAG_PERIODIC);
    if(simple_timer == RT_NULL) {
        rt_kprintf("create simple_timer failed!\r\n");
        rt_event_delete(simple_page_evt);
        return ;
    }
    simple_page_t page_instance;
    simple_page_page_t temp_page_page;
    simple_page_page_t page_page;
//    simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_BACK, simple_page_event_do_nothing, RT_NULL);
//    simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_NEXT, simple_page_event_do_nothing, RT_NULL);
//    simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_PREV, simple_page_event_do_nothing, RT_NULL);
//    simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_OK, simple_page_event_ok_callback, RT_NULL);
    page_instance = simple_page_create(simple_page_event_wait);
    simple_page_add_event(page_instance, SIMPLE_PAGE_EVENT_ALARM, simple_page_alarm, RT_NULL);
    page_page = simple_page_page_create("clock", simple_clock_page_draw, RT_NULL);
    if(page_page != RT_NULL) {
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_IN, simple_clock_page_draw, RT_NULL);
        // set "clock" page to home.
        simple_page_set_home_page(page_instance, page_page);
        temp_page_page = page_page;
        page_page = simple_page_page_new(temp_page_page, "exit", simple_clock_page_draw, RT_NULL, simple_page_page_add_child);
    }
    if(page_page != RT_NULL) {
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_IN, simple_clock_page_draw, RT_NULL);
        temp_page_page = page_page;
        page_page = simple_page_page_new(temp_page_page, "stopwatch", simple_stopwatch_page_draw, RT_NULL, simple_page_page_add_next);
    }
    if(page_page != RT_NULL) {
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_BACK, simple_page_event_do_nothing, RT_NULL);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_OK, simple_page_event_ok_callback, RT_NULL);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_IN, simple_stopwatch_page_draw, RT_NULL);
        //"stopwatch"'s subpage
        temp_page_page = page_page;
        page_page = simple_page_page_new(temp_page_page, "subpage", RT_NULL, RT_NULL, simple_page_page_add_child);
    }
    if(page_page != RT_NULL) {
        static struct _user_param stopwatch_param;
        rt_memset(&stopwatch_param, 0, sizeof(stopwatch_param));
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_NEXT, simple_page_event_prev_or_next_callback, &stopwatch_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_PREV, simple_page_event_prev_or_next_callback, &stopwatch_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_OK, simple_page_event_ok_callback, &stopwatch_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_IN, simple_stopwatch_page_draw, &stopwatch_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_DRAW, simple_stopwatch_page_draw, &stopwatch_param);
        //"setting"
        page_page = simple_page_page_new(temp_page_page, "setting", simple_setting_page_draw, RT_NULL, simple_page_page_add_next);
    }
    if(page_page != RT_NULL) {
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_BACK, simple_page_event_do_nothing, RT_NULL);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_OK, simple_page_event_ok_callback, RT_NULL);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_IN, simple_setting_page_draw, RT_NULL);
        //"setting"'s subpage
        temp_page_page = page_page;
        page_page = simple_page_page_new(temp_page_page, "subpage", RT_NULL, RT_NULL, simple_page_page_add_child);
    }
    if(page_page != RT_NULL) {
        static struct _user_param setting_param;
        rt_memset(&setting_param, 0, sizeof(setting_param));
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_NEXT, simple_page_event_prev_or_next_callback, &setting_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_PREV, simple_page_event_prev_or_next_callback, &setting_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_OK, simple_page_event_ok_callback, &setting_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_IN, simple_setting_page_draw, &setting_param);
        simple_page_page_add_event(page_page, SIMPLE_PAGE_PAGE_EVENT_DRAW, simple_setting_page_draw, &setting_param);
    }
    if(page_page == RT_NULL) {
        simple_page_destroy(page_instance);
        rt_event_delete(simple_page_evt);
        rt_timer_delete(simple_timer);
        rt_kprintf("create page failed!\r\n");
        return ;
    }
    rt_timer_start(simple_timer);
    while(1) {
        simple_page_process(page_instance);
    }
}
int simple_page_task_init(void)
{
    rt_thread_t tid;
    tid = rt_thread_create("simple_page", simple_page_task, RT_NULL, 4096, 10, 10);
    if(tid != RT_NULL) {
        rt_thread_startup(tid);
        return 0;
    }
    return -1;
}

